package com.game.service.socket;

import java.lang.reflect.Type;
import java.net.InetSocketAddress;
import java.util.*;

import com.game.service.app.MD5Util;
import com.game.service.app.get_score.Money;
import com.game.service.app.Score;
import com.game.service.app.order.*;
import com.game.service.beans.*;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.game.service.define.GameDefine;
import org.java_websocket.WebSocket;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;


import static com.game.service.app.Score.*;
import static com.game.service.define.GameDefine.*;
import static com.game.service.define.RoomConfig.*;


public class SocketServer extends WebSocketServer {
    /**
     * 房间共用信息
     */
    RoomInfo roomInfo = new RoomInfo();

    /**
     * 房间内玩家信息 最后结算以此为基础
     */
    ArrayList<UserInfo> userInfos = new ArrayList<>();
    /**
     * 储存的是押注信息
     */
    ArrayList<UserInfo> userPlayBets = new ArrayList<>();
    /**
     * 超时订单,需要返回的
     */
    ArrayList<UserInfo> outTimeOrders = new ArrayList<>();
    /**
     * 玩家websocket维护列表
     */
    HashMap<Integer, WebSocket> webSocketHashMap = new HashMap<>();
    /**
     * 客户端发送投注指令计数标志
     */
    private int betId = 0;

    /**
     * 总服务器下单完成计数标志
     */
    private int betReturnId = 0;

    private int[] gamePoints;

    public int getGamePoints() {
        int total = 0;
        for (int gamePoint : gamePoints) {
            total += gamePoint;
        }
        return total;
    }

    GameControl gameControl;

    public SocketServer(int port) {
        super(new InetSocketAddress(port));

        roomInfo.firstTime = FileUtils.getTime();
        gameControl = new GameControl();
        gameControl.init(this);
        userInfos.add(gameControl.getNo1Robot().userInfo);
        userInfos.add(gameControl.getNo2Robot().userInfo);


        resetGameData();
        onGameRun();
    }


    @Override
    public void onOpen(WebSocket conn, ClientHandshake handshake) {

        // conn.send("Welcome to the server!"); // This method sends a message to the new client
        String ip = conn.getRemoteSocketAddress().getAddress().getHostAddress();
        int port = conn.getRemoteSocketAddress().getPort();
        System.out.println(ip + ":" + port + " ,entered the room!");
        int size = this.getConnections().size();
        System.out.println("连接数量=" + size);

        send(conn, GameDefine.GAME_MAIN, GameDefine.GAME_SUB_SOCKET_SUCCESS, null);
    }


    @Override
    public void onClose(WebSocket conn, int code, String reason, boolean remote) {
        //  broadcast(conn + " has left the room!");
        System.out.println("onClose:" + " has left the room!" + code + reason);

    }

    @Override
    public void onMessage(WebSocket conn, String message) {
        System.out.println(FileUtils.getTime() + "onMessage: " + message);

        try {
            Gson gson = new Gson();
            GameMessage gameMessage = gson.fromJson(message, GameMessage.class);
            final int main = gameMessage.main;
            final int sub = gameMessage.sub;
            switch (main) {
                case GAME_MAIN:
                    //猜大小游戏消息
                    onSub(conn, sub, message);
                    break;
                case 201:
                    //其他游戏预留
                    break;
                case 0:
                    if (sub == 0) {
                        send(conn, GameDefine.GAME_MAIN, GameDefine.GAME_SUB_SOCKET_SUCCESS, null);

                    }

                    break;
                default:
                    break;
            }

        } catch (Exception e) {
            System.out.println("======" + e.toString());
            FileUtils.writeTxtToFile(e.toString(),OutFilePath,"err.txt");

        }


    }


    @Override
    public void onError(WebSocket conn, Exception ex) {
        ex.printStackTrace();
        if (conn != null) {
            // some errors like port binding failed may not be assignable to a specific
            // websocket
        }

    }

    @Override
    public void onStart() {
        System.out.println("Server started!");
        setConnectionLostTimeout(0);
        setConnectionLostTimeout(100);

    }


    private void onSub(WebSocket conn, int sub, String json) {
        Gson gson = new Gson();
        if (sub == GAME_C_SUB_ENTER_ROOM) {
            long start = System.currentTimeMillis();
            EnterRoom(conn, json, gson);
            System.out.println("EnterRoom=" + (System.currentTimeMillis() - start));
        }

        if (sub == GAME_C_SUB_BET) {
            long start = System.currentTimeMillis();
            GameBetToScoreServer(conn, json, gson);
            System.out.println("GameBet=" + (System.currentTimeMillis() - start));
        }
        if (sub == GAME_C_SUB_LEAVE_ROOM) {
            LeaveRoom(conn, json, gson);
        }

        if (sub == GAME_C_SUB_GET_SCORE) {

            GetScore(conn, json, gson);
        }
    }

    private void GetScore(WebSocket conn, String json, Gson gson) {
        //获取分数
        Type type = new TypeToken<GameMessage<Login>>() {
        }.getType();//无敌好用
        GameMessage<Login> data = gson.fromJson(json, type);
        final Login login = data.cmd;

        new Thread(() -> {

            String json0 = gson.toJson(login);
            System.out.println(FileUtils.getTime() + data +",请求地址"+API_GET_COIN +"数据"+json0);

            String result = doPostForm(API_GET_COIN, json0);

            Type type0 = new TypeToken<JsonBean<Money>>() {
            }.getType();

            JsonBean<Money> bean = gson.fromJson(result, type0);

            System.out.println(FileUtils.getTime() + bean.toString());

            if (bean.code == 0) {

                UserInfo user = getUser(login.uid);
                if (user == null) {
                    //如果获取为空，则添加新玩家
                    UserInfo newUser = new UserInfo();
                    newUser.id = login.uid;
                    newUser.mac = login.token;
                    newUser.liveid = login.liveid;
                    newUser.stream = login.stream;
                    newUser.score = bean.data.coin;
                    newUser.status = 1;
                    userInfos.add(newUser);
                    sendUserInfoGameStart(conn, newUser);
                } else {
                    //如果获取为有，则修改在线状态,更新分数
                    user.score = bean.data.coin;
                    user.status = 1;
                    sendUserInfoGameStart(conn, user);
                }


            } else {

                sendErrorMsg(conn, bean.data);
            }

        }).start();
    }

    private UserInfo getUser(int uid) {
        //判断是否加入房间
        for (UserInfo user : userInfos) {
            //属于断线重连
            if (user.id == uid) {

                return user;
            }
        }
        return null;
    }

    private void LeaveRoom(WebSocket conn, String json, Gson gson) {

        Type type = new TypeToken<GameMessage<Login>>() {
        }.getType();//无敌好用
        GameMessage<Login> data = gson.fromJson(json, type);
        int id = data.cmd.uid;
        webSocketHashMap.remove(id);//玩家离开房间，移除连接保存
        for (UserInfo userInfo : userInfos) {
            if (userInfo.id == id) {
                userInfo.status = 1000;//玩家离开，本局游戏结算后移除
                break;
            }
        }

    }

    private void EnterRoom(WebSocket conn, String json, Gson gson) {
        //玩家进入房间
        Type type = new TypeToken<GameMessage<Login>>() {
        }.getType();//无敌好用
        GameMessage<Login> data = gson.fromJson(json, type);

        final int id = data.cmd.uid;
        webSocketHashMap.put(id, conn);


        UserInfo user = getUser(id);
        if (user != null) {
            if (user.liveid == data.cmd.liveid) {
                //同一个直播间,直接断线重连
                user.status = 1;
                sendUserInfoGameStart(conn, user);
            } else {
                if (user.status == 0) {//已经结算,则可以去其他直播间玩
                    user.status = 1;
                    user.liveid = data.cmd.liveid;
                    user.stream = data.cmd.stream;
                    sendUserInfoGameStart(conn, user);
                } else {//未结算,返回等待下一局
                    user.status = 2;

                    sendUserInfoGameStart(conn, user);
                }
            }
            //TODO 玩家可能会离开A直播间,去B直播间玩同一款游戏。当前如果是掉线离开则会保存A直播间的信息
            return;
        }
        GetScore(conn, json, gson);

    }


    public void GameBetReturn(WebSocket conn, UserInfo userInfo) {
        userInfo.betReturnId = ++betReturnId;
        System.out.println(FileUtils.getTime() + userInfo);
        if (remainingSeconds <= ORDER_STOP_TIME) {
            outTimeOrders.add(userInfo);//超时订单
            System.out.println("接收总服务器超时订单");
            return;
        }

        userPlayBets.add(userInfo);
        if (userInfo.select == 1) {
            roomInfo.bigPeople += 1;
            roomInfo.bigTotal += userInfo.betScore;
            updateUserInfo(conn, userInfo);
        }
        if (userInfo.select == 2) {
            roomInfo.smallPeople += 1;
            roomInfo.smallTotal += userInfo.betScore;
            updateUserInfo(conn, userInfo);
        }
        roomInfoUpdate(conn);


    }

    private void GameBetToScoreServer(WebSocket conn, String json, Gson gson) {
        if (remainingSeconds <= GAME_SERVER_ORDER_STOP_TIME) {
            return;
        }
        Type type = new TypeToken<GameMessage<UserInfo>>() {
        }.getType();//无敌好用

        GameMessage<UserInfo> data = gson.fromJson(json, type);
        UserInfo userInfo = data.cmd;
        if (userInfo.betScore == 0) {
            updateUserInfo(conn, userInfo);
            //直接返回玩家信息
            return;
        }

        // for (int i = 0; i < 10; i++) {
        userInfo.betId = ++betId;//
        //客户单不传值。
        toScoreServer(userInfo);
        // }

    }


    void send(WebSocket conn, int main, int sub, Object cmd) {

        if (conn == null) {

            return;
        }
        Gson gson = new Gson();
        GameMessage gameMessage = new GameMessage();
        gameMessage.main = main;
        gameMessage.sub = sub;
        gameMessage.cmd = cmd;
        String json = gson.toJson(gameMessage);
        if (conn.getReadyState() == ReadyState.OPEN) {
            conn.send(json);
        }

        // System.out.println(conn.getReadyState()+","+main+"-"+sub);
    }


    public static int[] random() {
        int[] points = new int[3];
        Random random = new Random();
        int num1 = points[0] = random.nextInt(6) + 1;
        int num2 = points[1] = random.nextInt(6) + 1;
        int num3 = points[2] = random.nextInt(6) + 1;
        int total = num1 + num2 + num3;

        System.out.println("Random numbers: " + num1 + ", " + num2 + ", " + num3 + " ,Total:" + total + " 结果:" + (total > 10 ? "大" : "小"));
        return points;
    }

    private ArrayList<Integer> gameList = new ArrayList<>();
    private int remainingSeconds = GAME_TIME;

    /**
     * 服务器开启成功后运行游戏线程
     */
    public void onGameRun() {
        CountdownTimer countdown = new CountdownTimer(GAME_TIME); // 30秒倒计时
        TimerTask task = new TimerTask() {

            public void run() {
                try {
                    MyGameRun();
                } catch (Exception e) {
                    System.out.println(e.toString());
                    FileUtils.writeTxtToFile(e.toString(),OutFilePath,"err.txt");
                }

            }

            private void MyGameRun() {
                if (remainingSeconds > 0) {
                    //游戏开始倒计时
                    GameStart();
                } else if (remainingSeconds == 0) {
                    //倒计时=0,下发游戏结果,与得分信息
                    RoomSendGameResult();
                    //写分
                    WriteScore();
                } else if (remainingSeconds > -5) {
                    System.out.println("开奖动画时间: " + remainingSeconds + " 秒");
                } else if (remainingSeconds == -5) {

                    //超时退单
                    toScoreServerOrderReturn(RETURN_TYPE_TIMEOUT, outTimeOrders);
                    //重置
                    resetGameData();
                }
                remainingSeconds--;
            }
        };
        countdown.startTimer(task);
    }

    private void GameStart() {
        System.out.println(FileUtils.getTime() + "开奖倒计时: " + remainingSeconds + " 秒,");
        roomInfo.gameTimes = remainingSeconds;

        if (remainingSeconds == 2) {
            long start = System.currentTimeMillis();
            returnScore();
            System.out.println("returnScore=" + (System.currentTimeMillis() - start));
            roomInfoNewTotal();
            roomInfoUpdate();
        } else {
            roomInfoUpdate();
        }


        if (remainingSeconds > 5 && remainingSeconds % 2 == 0) {
            //V1.04新增处理事务。
            // gameControl.deal();
            //  gameControl.playerRobot();

        }

    }

    private void roomInfoUpdate() {
        for (UserInfo userInfo : userInfos) {
            //同步到所有连接的客户端
            roomInfoUpdate(webSocketHashMap.get(userInfo.id));
        }
    }

    private void WriteScore() {
        ArrayList<GamesResult> list = new ArrayList<>();
        for (UserInfo userInfo : userInfos) {
            //同步到所有连接的客户端
            WebSocket conn = webSocketHashMap.get(userInfo.id);
            sendUserInfoGameStart(conn, userInfo);//刷新个人分数

            //打印与日志
            System.out.println(FileUtils.getTime() + "WriteScore() " + userInfo);
            FileUtils.writeTxtToFile(userInfo.toString(), OutFilePath, userInfo.id + "-log.txt");
            //统计投注的玩家
            GamesResult game = new GamesResult();
            game.uid = userInfo.id;
            game.num = userInfo.winScore;
            if (game.num>0) {
                game.profit=userInfo.winScore-userInfo.betScoreTotal;
            }
            game.bettingNum=userInfo.betScoreTotal;
            game.liveid = userInfo.liveid;
            game.stream = userInfo.stream;
            if (game.num != 0) {
                list.add(game);
            }
        }

        //有投注的情况写分到数据库,

        if (!list.isEmpty()) {
            new Thread(() -> {
                OrderGames order = new OrderGames();
                order.orderid = orderId();
                order.result = list;
                order.addtime = System.currentTimeMillis();
                Gson gson = new Gson();
                String json = gson.toJson(order);
                System.out.println(json);
                order.sign = MD5Util.encryptMD5(json + KEY);
                json = gson.toJson(order);
                //打印与日志
                String log = "结算 " + json;
                System.out.println(FileUtils.getTime() + log);
                FileUtils.writeTxtToFile(log, OutFilePath, LOG_NAME_ROOM_BET);

                String result = doPostForm(API_WRITE_SCORE, json);
                //打印与日志
                System.out.println(FileUtils.getTime() + result);
                FileUtils.writeTxtToFile(result, OutFilePath, LOG_NAME_ROOM_BET);


            }).start();
        }


        //移除断线或者离开的的玩家。
        userInfos.removeIf(userInfo -> userInfo.status != 1);

    }

    private void RoomSendGameResult() {
        GameResult cmd = new GameResult();
        cmd.gameId = orderId();//游戏场次编号
        cmd.points = gamePoints;
        int total = cmd.points[0] + cmd.points[1] + cmd.points[2];
        gameList.add(total);
        if (total > 10) {
            roomInfo.openBig++;
        } else {
            roomInfo.openSmall++;
        }
        System.out.println("房间信息:" + roomInfo);

        for (UserInfo userInfo : userInfos) {
            sendGameResult(userInfo, cmd);
        }

        System.out.println("发送结果: " + Arrays.toString(cmd.points));
    }

    void resetGameData() {
        //每局游戏需要一个唯一编号
        roomInfo.gameCurrentTimeMillis = System.currentTimeMillis();
        roomInfo.bigTotal = 0;
        roomInfo.bigPeople = 0;
        roomInfo.smallTotal = 0;
        roomInfo.smallPeople = 0;
        remainingSeconds = GAME_TIME + 1;
        roomInfo.games += 1;
        roomInfo.gameList = getGameList();
        //重置用户押注信息
        clearAllBet();
        betId = 0;//重置为0
        betReturnId = 0;//重置为0
        userPlayBets.clear();
        outTimeOrders.clear();
        System.out.println("重置开始新的一局" + roomInfo.games);
        gamePoints = random();//内部初始化本局游戏结果
        gameControl.no1Robot.isAdd = false;
        gameControl.no2Robot.isAdd = false;
    }

    //进入房间时获取玩家的信息,并且发送给玩家,并且开始游戏
    void sendUserInfoGameStart(WebSocket conn, UserInfo cmd) {
        sendUserInfoUpdate(conn, cmd);
    }

    //进入房间时获取玩家的信息,并且发送给玩家,并且开始游戏
    void sendErrorMsg(WebSocket conn, Object cmd) {
        send(conn, GAME_MAIN, 4, cmd);
    }

    void sendUserInfoUpdate(WebSocket conn, UserInfo cmd) {
        UserInfo userInfo = new UserInfo();

        userInfo.id = cmd.id;
        userInfo.name = cmd.name;
        userInfo.score = cmd.score;
        userInfo.mac = cmd.mac;
        userInfo.status = cmd.status;
        userInfo.betScore = cmd.betScore;
        userInfo.betScoreTotal = cmd.betScoreTotal;
        userInfo.select = cmd.select;
        userInfo.betId = cmd.betId;

        send(conn, GAME_MAIN, GAME_SUB_UPDATE_USERINFO, userInfo);
    }


    void roomInfoUpdate(WebSocket conn) {
        RoomInfo cmd = new RoomInfo();
        cmd.gameTimes = roomInfo.gameTimes;
        cmd.bigPeople = roomInfo.bigPeople;
        cmd.smallPeople = roomInfo.smallPeople;
        cmd.bigTotal = roomInfo.bigTotal;
        cmd.smallTotal = roomInfo.smallTotal;
        cmd.games = roomInfo.games;
        cmd.gameList = roomInfo.gameList;

        send(conn, GAME_MAIN, GAME_SUB_UPDATE_ROOMINFO, cmd);
    }

    int[] getGameList() {
        int[] list = new int[GAME_LIST_LENGTH];

        for (int i = 0; i < list.length; i++) {

            int a = gameList.size() - 1 - i;

            if (a >= 0) {
                list[i] = gameList.get(a);
            } else {
                list[i] = -1;
            }

        }
        return list;
    }


    void updateUserInfo(WebSocket conn, UserInfo userClient) {
        //user是本地数据,保存的是最后一次的押注信息
        for (UserInfo user : userInfos) {
            if (user.id == userClient.id) {
                //玩家分数,每次投注进行扣除
                user.score -= userClient.betScore;
                user.select = userClient.select;
                user.betScore = userClient.betScore;
                //本地统计,每次投注累加
                user.betScoreTotal += userClient.betScore;
                user.betId = userClient.betId;
                //应该返回给玩家以便UI显示
                sendUserInfoUpdate(conn, user);
                break;
            }
        }

        System.out.println("房间内" + userInfos.toString());
    }

    void clearAllBet() {
        for (UserInfo user : userInfos) {

            send(webSocketHashMap.get(user.id), GAME_MAIN, GAME_SUB_GAME_START, null);

            user.status = 0;//为1表示在线

            user.select = 0;
            user.betScore = 0;
            user.betScoreTotal = 0;
            user.betId = 0;
            user.betReturnId = 0;
            user.gameId = "";
            user.points = new int[]{0, 0, 0};
            user.winScore = 0;
            //20240911新增开局发送玩家信息
            sendUserInfoUpdate(webSocketHashMap.get(user.id), user);

        }
    }

    static ReturnModel bigMore(long smallTotal, ArrayList<UserInfo> userPlayBets) {


        ReturnModel info = new ReturnModel();
        info.select = 1;

        long bigTotal2 = 0;
        for (UserInfo userInfo : userPlayBets) {

            if (userInfo.select == 1) {
                bigTotal2 += userInfo.betScore;
                if (bigTotal2 >= smallTotal) {
                    long part = bigTotal2 - smallTotal;//退还分数
                    //TODO
                    info.betScore = part;
                    info.betId = userInfo.betReturnId;//下单成功编号记录

                    System.out.println("大退回" + part + userInfo.toString());
                    break;
                }
            }
        }

        return info;
    }

    static ReturnModel smallMore(long bigTotal, ArrayList<UserInfo> userPlayBets) {
        ReturnModel info = new ReturnModel();
        info.select = 2;
        //大的全部生效。小的按照前后顺序来接受
        long smallTotal2 = 0;

        for (UserInfo userInfo : userPlayBets) {
            if (userInfo.select == 2) {
                smallTotal2 += userInfo.betScore;
                if (smallTotal2 >= bigTotal) {

                    long part = smallTotal2 - bigTotal;//退还分数
                    //TODO 退回
                    info.betScore = part;
                    info.betId = userInfo.betReturnId;
                    System.out.println("小退回" + part + userInfo);
                    break;
                }
            }
        }

        return info;
    }


    void returnScore() {
        long bigTotal = 0;
        long smallTotal = 0;

        for (UserInfo userInfo : userPlayBets) {
            if (userInfo.select == 1) {
                bigTotal += userInfo.betScore;
            }
            if (userInfo.select == 2) {
                smallTotal += userInfo.betScore;
            }

        }

        ReturnModel model = new ReturnModel();
        if (bigTotal == smallTotal) {

            model.select = 0;

        } else if (bigTotal > smallTotal) {
            //小的全部有效。大的按照前后顺序来接受
            model = bigMore(smallTotal, userPlayBets);
            model.totalBig = bigTotal;
        } else {
            model = smallMore(bigTotal, userPlayBets);
            model.totalBig = smallTotal;
        }

        ArrayList<UserInfo> returnInfos = new ArrayList<>();

        if (returnModel == RETURN_MODEL.RATIO) {
            // returnInfos 需要合并相同玩家的押注
            HashMap<Integer, UserInfo> map = integrateOrders(userPlayBets);
            ArrayList<UserInfo> integrateList = new ArrayList<>();
            map.forEach((key, value) -> integrateList.add(value));


            //按照比例退分 用合并的新订单
            for (UserInfo userInfo : integrateList) {
                //先判断是退大还是退小
                if (userInfo.select == model.select) {
                    //计算差额
                    long sum = Math.abs(bigTotal - smallTotal);
                    float tScore = (sum * userInfo.betScore) * 1.0f / model.totalBig;
                    userInfo.betScore = Math.round(tScore);
                    System.out.println("退分" + userInfo.betScore);
                    returnInfos.add(userInfo);
                }
            }


            toScoreServerOrderReturn(RETURN_TYPE_BALANCE, returnInfos);


        } else if (returnModel == RETURN_MODEL.SEQUENCE) {

            //  按照先来先得模式
            for (UserInfo userInfo : userPlayBets) {
                //零界点的退分
                if (model.betId == userInfo.betReturnId) {
                    userInfo.betScore = model.betScore;
                    returnInfos.add(userInfo);//零界点订单
                }
                //零界点之后的全部都要退分
                if (userInfo.betReturnId > model.betId && model.select == userInfo.select) {
                    returnInfos.add(userInfo);//平衡退单
                }

            }

            //直接处理
            toScoreServerOrderReturn(RETURN_TYPE_BALANCE, returnInfos);
        }


        for (UserInfo userInfo : userInfos) {
            for (UserInfo returnInfo : returnInfos) {
                if (userInfo.id == returnInfo.id) {
                    userInfo.betScoreTotal -= returnInfo.betScore;
                    userInfo.score += returnInfo.betScore;
                }
            }
            //同步每个玩家的最终分数
            sendUserInfoUpdate(webSocketHashMap.get(userInfo.id), userInfo);
        }

    }

    /**
     * @param type        退单类型，0平衡退单，1超时退单
     * @param returnInfos 退单集合
     */

    private void toScoreServerOrderReturn(int type, ArrayList<UserInfo> returnInfos) {
        HashMap<Integer, OrderReturnBean> map = getOrder(returnInfos);

        ArrayList<OrderReturnBean> list = new ArrayList<>();
        // 填充map
        map.forEach((key, value) -> list.add(value));

        sendOrderReturn(type, list);
    }

    private void sendOrderReturn(int type, ArrayList<OrderReturnBean> list) {
        final String typeString = (type == 0 ? "平衡退单:" : "超时退单:");
        System.out.println(typeString + list.toString());
        if (!list.isEmpty()) {
            new Thread(() -> {
                OrderReturn order = new OrderReturn();
                order.orderid = orderId();
                order.orderReturns = list;
                order.addtime = System.currentTimeMillis();
                Gson gson = new Gson();
                String json = gson.toJson(order);
                order.sign = MD5Util.encryptMD5(json + KEY);
                json = gson.toJson(order);
                //打印与日志
                System.out.println(FileUtils.getTime() + typeString + json);
                FileUtils.writeTxtToFile(typeString + json, OutFilePath, LOG_NAME_ROOM_BET);

                String result = doPostForm(API_RETURN_ORDER, json);
                JsonBean jsonBean = new Gson().fromJson(result, JsonBean.class);
                if (jsonBean.code == 0) {
                    // 处理成功 此时同步所有玩家信息
                    if (type == 1) {
                        outTimeOrders.clear();
                    }

                }
                //打印与日志
                System.out.println(FileUtils.getTime() + typeString + result);
                FileUtils.writeTxtToFile(typeString + result, OutFilePath, LOG_NAME_ROOM_BET);


            }).start();
        }
    }

    private HashMap<Integer, UserInfo> integrateOrders(ArrayList<UserInfo> returnInfos) {
        HashMap<Integer, UserInfo> map = new HashMap<>();

        for (UserInfo userInfo : returnInfos) {
            UserInfo order = map.get(userInfo.id);
            if (order == null) {
                map.put(userInfo.id, userInfo);
            } else if (order.id == userInfo.id) {
                order.betScore += userInfo.betScore;
            }
        }
        return map;
    }


    private HashMap<Integer, OrderReturnBean> getOrder(ArrayList<UserInfo> returnInfos) {
        HashMap<Integer, OrderReturnBean> map = new HashMap<>();

        for (UserInfo userInfo : returnInfos) {
            OrderReturnBean order = map.get(userInfo.id);
            if (order == null) {
                OrderReturnBean orderReturn = new OrderReturnBean();
                orderReturn.uid = userInfo.id;
                orderReturn.num = userInfo.betScore;
                orderReturn.coin_type = COIN_TYPE;
                map.put(userInfo.id, orderReturn);
            } else if (order.uid == userInfo.id) {
                order.num += userInfo.betScore;
            }
        }
        return map;
    }

    void toScoreServer(final UserInfo userInfo) {
        //往总服务器同步分数,即下单
        OrderRequestBean order = new OrderRequestBean();
        order.uid = userInfo.id;
        order.token = userInfo.mac;
        order.type = COIN_TYPE;
        order.num = userInfo.betScore;//游戏服务器转发每次都投注
        order.orderid = orderId();
        order.countid = userInfo.betId + "";
        order.liveid = userInfo.liveid;
        order.stream = userInfo.stream;

        if (order.num > 0) {
            new Thread(() -> {
                String json = new Gson().toJson(order);
                //打印与日志
                System.out.println(FileUtils.getTime() + json);
                FileUtils.writeTxtToFile(json, OutFilePath, userInfo.id + "-log.txt");
                String result = doPostForm(Score.API_ORDER, json);

                JsonBean bean = new Gson().fromJson(result, JsonBean.class);
                if (bean != null && bean.code == 0) {
                    //TODO
                    System.out.println(FileUtils.getTime() + "购买成功");
                    GameBetReturn(webSocketHashMap.get(userInfo.id), userInfo);
                } else {
                    System.out.println("购买失败");
                }
                //打印与日志
                System.out.println(FileUtils.getTime() + result);
                FileUtils.writeTxtToFile(result, OutFilePath, userInfo.id + "-log.txt");
            }).start();
        }
    }

    String orderId() {
        return "game_" + roomInfo.gameCurrentTimeMillis + "_" + roomInfo.games;
    }

    void roomInfoNewTotal() {
        long bigTotal = 0;
        long smallTotal = 0;
        for (UserInfo userInfo : userInfos) {
            if (userInfo.select == 1) {
                bigTotal += userInfo.betScoreTotal;

            }
            if (userInfo.select == 2) {
                smallTotal += userInfo.betScoreTotal;

            }
        }
        roomInfo.smallTotal = smallTotal;
        roomInfo.bigTotal = bigTotal;
    }

    void sendGameResult(UserInfo userInfo, GameResult cmd) {
        int total = cmd.points[0] + cmd.points[1] + cmd.points[2];
        boolean big = total > 10;

        cmd.id = userInfo.id;//添加ID
        //同步游戏结果,发送给每个在线用户
        userInfo.gameId = cmd.gameId;
        userInfo.points = cmd.points;

        if (big && userInfo.select == 1 || !big && userInfo.select == 2) {
            cmd.winScore = Math.round(userInfo.betScoreTotal * (2 - COMMISSION));
            userInfo.score += cmd.winScore;
            userInfo.winScore = cmd.winScore;
        } else if (userInfo.select == 0 || userInfo.betScoreTotal == 0) {
            cmd.winScore = 0;
        } else {
            cmd.winScore = -1;
            userInfo.winScore = -1 * userInfo.betScoreTotal;
        }
        send(webSocketHashMap.get(userInfo.id), GAME_MAIN, GAME_SUB_GAME_RESULT, cmd);
    }

}


